﻿using Jet.Payment.Cielo.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace Jet.Payment.Cielo
{
    public static class Utils
    {
        private const string @namespace = "http://ecommerce.cbmp.com.br";
        private const string encodingDefault = "ISO-8859-1";

        internal static TResponse Request<TResponse, TRequest>(TRequest request)
            where TResponse : class
            where TRequest : class
        {
            var encoding = Encoding.GetEncoding(encodingDefault);
            var xml = ToXML<TRequest>(request);
            var postData = string.Format("mensagem={0}", xml);
            var postDataByte = encoding.GetBytes(postData);
            var url = Config.Environment == Model.Environment.Test ? Config.TestURL : Config.LiveURL;
            var wr = WebRequest.Create(url);
            wr.Method = "POST";
            wr.ContentType = "application/x-www-form-urlencoded";
            wr.ContentLength = postDataByte.Length;
            var stream = wr.GetRequestStream();
            stream.Write(postDataByte, 0, postDataByte.Length);
            stream.Flush();
            stream.Close();


            StreamReader sr = new StreamReader(wr.GetResponse().GetResponseStream());
            xml = sr.ReadToEnd();

            if (!string.IsNullOrEmpty(xml) && xml.Contains("<erro"))
                throw new PaymentException(FromXML<Error>(xml));

            return FromXML<TResponse>(xml);
        }

        private static string ToXML<T>(T obj) where T : class
        {
            var encoding = Encoding.GetEncoding(encodingDefault);
            using (var ms = new MemoryStream())
            using (var sw = new StreamWriter(ms, encoding))
            using (var writer = new XmlTextWriter(sw))
            {
                var ser = new XmlSerializer(typeof(T), @namespace);
                writer.Formatting = Formatting.Indented;
                ser.Serialize(writer, obj);
                ser = null;
                return encoding.GetString(ms.ToArray());
            }
        }

        private static T FromXML<T>(string xml) where T : class
        {
            var encoding = Encoding.GetEncoding(encodingDefault);
            using (var ms = new MemoryStream(encoding.GetBytes(xml)))
            {
                var ser = new XmlSerializer(typeof(T), @namespace);
                return ser.Deserialize(ms) as T;
            }
        }

        public static decimal ConvertValueFromCielo(string value)
        {
            var vl = value;
            if (vl.Length > 2)
                vl = vl.Insert(vl.Length - 2, ",");
            decimal castValue;
            if (decimal.TryParse(vl, System.Globalization.NumberStyles.Currency, System.Globalization.CultureInfo.GetCultureInfo("pt-BR"), out castValue))
                return castValue;
            else
                return 0;
        }

        public static string ConvertValueToCielo(decimal value)
        {
            return value.ToString(System.Globalization.CultureInfo.GetCultureInfo("pt-BR")).Replace(".", "").Replace(",", "");
        }
    }
}
